#include<iostream>
#include<assert.h>
#include<unistd.h>
#include<string>
#include<cstring>
#include<cstdio>
#include<sys/wait.h>
#include<sys/types.h>

using namespace std;

//不能定义全局buffer，因为有写时拷贝，无法更改通信!

int main()
{
    //1.创建管理
    int pipefd[2]={0};//【0】:读端；[1]：写端
    int n=pipe(pipefd);
    assert(n!=-1);
    (void)n;//证明n被使用过，仅此而已
#ifdef DEBUG
    cout<<"pipefd[0]:"<<pipefd[0]<<endl;//3
    cout<<"pipefd[1]:"<<pipefd[1]<<endl;//4
#endif

    //2.创建子进程
    pid_t id=fork();
    assert(id!=-1);
    if(id==0)
    {
        //子进程
        //3.构建单向通信的信道，父进程写入，子进程读取
        //3.1关闭子进程不需要的fd
        close(pipefd[1]);
        char buffer[1024*8];
        while(true)
        {
            //sleep(20);
            //写入的一方，fd没有关闭，如果有数据，就读，没有就等待
            //写入的一方，fd关闭，读取的一方，read会返回0，表示读到了文件的结尾
            ssize_t s=read(pipefd[0],buffer,sizeof(buffer)-1);
            if(s>0)
            {
                buffer[s]=0;
                cout<<"child get a message["<<getpid()<<"]"<<"Father#"<<buffer<<endl; 
                
            }
            else if(s==0)
            {
                cout<<"write quit(child),me quit!!!"<<endl;
                break;
            }
        }
        exit(0);
    }
    //父进程
    //3.构建单向通信的信道
    //3.1关闭父进程不需要的fd
    close(pipefd[0]);
    string message="我是父进程，我正在给你发信息";
    int count=0;
    char send_buffer[1024*8];

    while(true)
    {
        //3.2构建一个变化的字符串
        snprintf(send_buffer,sizeof(send_buffer),"%s[%d]:%d",
                    message.c_str(),getpid(),count++);//将字符串格式化到send_buffer中
        //3.3写入
        write(pipefd[1],send_buffer,strlen(send_buffer));
        //3.4sleep
        sleep(1);
        cout<< count <<endl;
        if(count==30)
        {
            cout<<"write quit(father)"<<endl;
            break;
        }
    }
    close(pipefd[1]);

    pid_t ret=waitpid(id,nullptr,0);
    cout<<"id: "<< id <<" ret: "<< ret <<endl;
    assert(ret>0);
    (void)ret;
   // close(pipefd[1]);

    return 0;
}